#include "basedriver.h"
#include <signal.h>
#include "wheeltec_mic_msg/msg/pcm_msg.hpp"
#include "wheeltec_mic_msg/srv/get_awake_anglesrv.hpp"
#include <thread>
#include <pthread.h>
#include "wheeltec_mic_msg/srv/get_major_micsrv.hpp"
#include "wheeltec_mic_msg/srv/get_offline_resultsrv.hpp"
#include "wheeltec_mic_msg/srv/set_awake_wordsrv.hpp"
#include "wheeltec_mic_msg/srv/set_led_onsrv.hpp"
#include "wheeltec_mic_msg/srv/set_major_micsrv.hpp"
#include "wheeltec_mic_msg/srv/start_recordsrv.hpp"

sensor_msgs::msg::Imu Mpu6050;
bool need_exit = false;

int offline_recognise_switch = 0; //离线识别默认开关
std::vector<char> pcm_buf;		  //音频流缓冲区

bool Get_request_mic_id = false;
bool Set_request_mic_id = false;
bool Set_request_led_id = false;
bool Set_request_awake_word = false;
bool Get_request_awake_angle = false;
using namespace std;

extern UserData asr_data;
extern int whether_finised ;
extern char *whole_result;

int write_first_data = 0;
int set_led_id ;

std::string awake_angle_topic = "/mic/awake/angle";
std::string pcm_topic = "/mic/pcm/deno";
std::string major_mic_topic = "/mic/major_mic";

std::string voice_words = "voice_words";

std::string voice_flag = "voice_flag";

std::string awake_flag = "awake_flag";

rclcpp::Publisher<std_msgs::msg::String>::SharedPtr voice_words_pub;
rclcpp::Publisher<std_msgs::msg::Int8>::SharedPtr awake_flag_pub;
rclcpp::Publisher<std_msgs::msg::Int8>::SharedPtr voice_flag_pub;
rclcpp::Publisher<wheeltec_mic_msg::msg::PcmMsg>::SharedPtr pub_pcm;
rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr pub_awake_angle;
rclcpp::Publisher<std_msgs::msg::Int8>::SharedPtr major_mic_pub;
//rclcpp::Publisher<std_msgs::msg::Int8>::SharedPtr recognise_result_pub;

rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtr sub_record_start;
// rclcpp::Subscription<std_msgs::msg::Int8>::SharedPtr sub_targrt_led_on;
// rclcpp::Subscription<std_msgs::msg::Int8>::SharedPtr sub_get_major_mic;


/*获取文件大小*/
int FileSize(const char *fname)
{
	struct stat statbuf;
	if (stat(fname, &statbuf) == 0)
		return statbuf.st_size;
	return -1;
}
std::wstring s2ws(const std::string &str)
{
	using convert_typeX = std::codecvt_utf8<wchar_t>;
	std::wstring_convert<convert_typeX, wchar_t> converterX;

	return converterX.from_bytes(str);
}

std::string ws2s(const std::wstring &wstr)
{
	using convert_typeX = std::codecvt_utf8<wchar_t>;
	std::wstring_convert<convert_typeX, wchar_t> converterX;

	return converterX.to_bytes(wstr);
}

//判断是否是整数
int isnumber(char *a, int count_need)
{
	int len = strlen(a);
	if (len > count_need)
	{
		return -1;
	}
	int j = 0;
	for (int i = 0; i < len; i++)
	{
		if (a[i] <= 57 && a[i] >= 48)
		{
			j++;
		}
	}
	if (j == len)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}


//字符串与字符数组拼接
/*char *join(std::string b, char *s2)
{
	char s1[600] = "";
	try
	{
		strcpy(s1, b.c_str());
	}
	catch (...)
	{
		cout << ">>>>>join拷贝失败" << endl;
	}
	char *result = (char *)malloc(strlen(s1) + strlen(s2) + 1);
	if (result == NULL)
		exit(1);

	try
	{
		strcpy(result, s1);
		strcat(result, s2);
	}
	catch (...)
	{
		cout << ">>>>>join拷贝失败" << endl;
	}
	return result;
}*/


//麦克风通信回调函数
int business_proc_callback(business_msg_t businessMsg)
{
	int res = 0;
	char *fileName = join(source_path, DENOISE_SOUND_PATH);
	char *fileName_ori = join(source_path, ORIGINAL_SOUND_PATH);
	static int index = 0;
	unsigned char buf[4096];
	//printf("business proc modId = %d, msgId = %d, size = %d", businessMsg.modId, businessMsg.msgId, businessMsg.length);
	switch (businessMsg.modId)
	{
	case 0x01:
		if (businessMsg.msgId == 0x01)
		{
			unsigned char key[] = "errcode";
			int status = whether_set_succeed(businessMsg.data, key);
			if (status == 0)
			{
				//printf(">>>>>您已开启录音\n");
			}
		}
		else if (businessMsg.msgId == 0x02)
		{
			int len = PCM_MSG_LEN;
			char *pcm_buffer = new char[len]; //在堆中创建空间
#if whether_print_log
			if (pcm_buffer == NULL)
			{
				cout << "buffer is null" << endl;
			}
			else
			{
				cout << "buffer alloced successfully" << endl;
			}
			//cout << "data size:" << businessMsg.length << "len:" << len << endl;
#endif
			try
			{
				memcpy(pcm_buffer, businessMsg.data, len);
			}
			catch (...)
			{
				cout << ">>>>>拷贝失败" << endl;
			}
			if (businessMsg.length < len)
			{
				len = businessMsg.length;
				cout << "businessMsg size is noenough" << endl;
			}
			if (save_pcm_local)
			{
				char *denoise_sound_path = join(source_path, DENOISE_SOUND_PATH);
				if (-1 != FileSize(denoise_sound_path))
				{
					int file_size = FileSize(denoise_sound_path);
					if (file_size > max_pcm_size) //超出最大文件限制,将删除,以节省磁盘空间
					{
						remove(denoise_sound_path);
					}
				}
				get_denoised_sound(denoise_sound_path, businessMsg.data);
			}
			/*写入第一块音频*/
			// if(is_awake)
			// {
			if (write_first_data++ == 0)
			{
#if whether_print_log
				printf("***************write the first voice**********\n");
#endif
				demo_xf_mic(pcm_buffer, len, 1);
			}

			else
			{
#if whether_print_log
				printf("***************write the middle voice**********\n");
#endif
				demo_xf_mic(pcm_buffer, len, 2);
			}
		}
		else if (businessMsg.msgId == 0x03)
		{
			unsigned char key[] = "errcode";
			int status = whether_set_succeed(businessMsg.data, key);
			if (status == 0)
			{
				//发布关闭前剩余的音频流
				wheeltec_mic_msg::msg::PcmMsg pcm_data;
				vector<char>::iterator it;
				for (it = pcm_buf.begin(); it != pcm_buf.end(); it++)
				{
					pcm_data.pcm_buf.push_back(*it);
				}
				pcm_data.length = pcm_buf.size();
				pub_pcm->publish(pcm_data);
				//pcm_buf->clear();
				printf(">>>>>您已停止录音\n");
			}
		}
		else if (businessMsg.msgId == 0x04)
		{
			unsigned char key[] = "errcode";
			int status = whether_set_succeed(businessMsg.data, key);
			if (status == 0)
			{
				printf(">>>>>开/关原始音频成功\n");
			}
		}
		else if (businessMsg.msgId == 0x05)
		{
			unsigned char key[] = "errcode";
			int status = whether_set_succeed(businessMsg.data, key);
			if (status == 0)
			{
				//printf(">>>>>设置主麦克风成功\n");
			}
		}
		else if (businessMsg.msgId == 0x06)
		{
			get_original_sound(fileName_ori, businessMsg.data);
		}
		else if (businessMsg.msgId == 0x07)
		{
			unsigned char key2[] = "beam";
			try
			{
				int major_id = whether_set_succeed(businessMsg.data, key2);
				major_mic_id = major_id;
				Get_request_mic_id = true;
				printf(">>>>>主麦克风id为%d号麦克风\n", major_mic_id);
			}
			catch (...)
			{
				Get_request_mic_id = false;
			}
		}
		else if (businessMsg.msgId == 0x08)
		{
			unsigned char key[] = "errcode";
			int status = whether_set_succeed(businessMsg.data, key);
			if (status == 0)
			{
				Set_request_mic_id = true;
				//printf("\n>>>>>设置主麦克风成功\n");
			}
			else
			{
				Set_request_mic_id = false;
			}
		}
		else if (businessMsg.msgId == 0x09)
		{
			unsigned char key[] = "errcode";
			int status = whether_set_succeed(businessMsg.data, key);
			if (status == 0)
			{
				Set_request_led_id = true;
				//printf("\n>>>>>设置灯光成功\n");
			}
			else
			{
				Set_request_led_id = false;
			}
		}

		break;
	case 0x02:
		if (businessMsg.msgId == 0x01)
		{
			unsigned char key1[] = "beam";
			unsigned char key2[] = "angle";
			major_mic_id = get_awake_mic_id(businessMsg.data, key1);
			mic_angle = get_awake_mic_angle(businessMsg.data, key2);
			if (major_mic_id <= 5 && major_mic_id >= 0 && mic_angle <= 360 && mic_angle >= 0)
			{
				if_awake = 1;
				led_id = get_led_based_angle(mic_angle);
				int ret1 = set_major_mic_id(major_mic_id);
				int ret2 = set_target_led_on(led_id);
				if (ret1 == 0 && ret2 == 0)
				{
					printf(">>>>>第%d个麦克风被唤醒\n", major_mic_id);
					printf(">>>>>唤醒角度为:%d\n", mic_angle);
					printf(">>>>>已点亮%d灯\n", led_id);
					Get_request_awake_angle = true;
					std_msgs::msg::Int32 awake_angle;
					awake_angle.data = mic_angle;
					pub_awake_angle->publish(awake_angle);

					std_msgs::msg::Int8 awake_flag_msg;
					awake_flag_msg.data = 1;
					awake_flag_pub->publish(awake_flag_msg);

					std_msgs::msg::Int8 majormic;
					majormic.data = major_mic_id;
					major_mic_pub->publish(majormic);

					std_msgs::msg::String msg;
					msg.data = "小车唤醒";
					voice_words_pub->publish(msg);
					
					whether_finised = 1;
					set_led_id = led_id;
					//printf("\n1111111111111111\n");
				}
			}
		}
		else if (businessMsg.msgId == 0x08)
		{
			unsigned char key1[] = "errstring";
			int result = whether_set_awake_word(businessMsg.data, key1);
			if (result==0)
			{
				Set_request_awake_word = true;
				//printf("\n>>>>>唤醒词设置成功\n");
			}
			else if (result==-2)
			{
				Set_request_awake_word = false;
				printf("\n>>>>>唤醒词设置失败\n");

			}
		}
		
		
		break;
	case 0x03:
		if (businessMsg.msgId == 0x01)
		{
			unsigned char key[] = "status";
			int status = whether_set_succeed(businessMsg.data, key);
			char protocol_version[40]; 
			int ret = get_protocol_version(businessMsg.data,protocol_version);
			printf(">>>>>麦克风%s,软件版本为:%s,协议版本为:%s\n", (status == 0 ? "正常工作" : "正在启动"),get_software_version(),protocol_version);
			if (status == 1)
			{
				char *fileName = join(source_path,SYSTEM_CONFIG_PATH);
				send_resource_info(fileName, 0);
			}
			else
			{
				is_boot = 1;
			}
		}

		break;

	case 0x04:
		if (businessMsg.msgId == 0x01)
		{
			whether_set_resource_info(businessMsg.data);
		}
		else if (businessMsg.msgId == 0x03) //文件接收结果
		{
			whether_set_resource_info(businessMsg.data);
		}
		else if (businessMsg.msgId == 0x04) //查看设备升级结果
		{
			whether_upgrade_succeed(businessMsg.data);
		}
		else if (businessMsg.msgId == 0x05) //下发文件
		{
			char *fileName_system_path = join(source_path, SYSTEM_PATH);
			;
			send_resource(businessMsg.data, fileName_system_path, 1);
		}
		else if (businessMsg.msgId == 0x08) //获取升级配置文件
		{
			printf("config.json: %s", businessMsg.data);
		}
		break;

	default:
		break;
	}
	return 0;
}


/*用于显示离线命令词识别结果*/
Effective_Result show_result(char *string) //
{
	Effective_Result current;
	if (strlen(string) > 250)
	{
		char asr_result[32];	//识别到的关键字的结果
		char asr_confidence[3]; //识别到的关键字的置信度
		char *p1 = strstr(string, "<rawtext>");
		char *p2 = strstr(string, "</rawtext>");
		int n1 = p1 - string + 1;
		int n2 = p2 - string + 1;

		char *p3 = strstr(string, "<confidence>");
		char *p4 = strstr(string, "</confidence>");
		int n3 = p3 - string + 1;
		int n4 = p4 - string + 1;
		for (int i = 0; i < 32; i++)
		{
			asr_result[i] = '\0';
		}

		strncpy(asr_confidence, string + n3 + strlen("<confidence>") - 1, n4 - n3 - strlen("<confidence>"));
		asr_confidence[n4 - n3 - strlen("<confidence>")] = '\0';
		int confidence_int = 0;
		confidence_int = atoi(asr_confidence);
		if (confidence_int >= confidence)
		{
			strncpy(asr_result, string + n1 + strlen("<rawtext>") - 1, n2 - n1 - strlen("<rawtext>"));
			asr_result[n2 - n1 - strlen("<rawtext>")] = '\0'; //加上字符串结束符。
		}
		else
		{
			strncpy(asr_result, "", 0);
		}

		current.effective_confidence = confidence_int;
		strcpy(current.effective_word, asr_result);
		return current;
	}
	else
	{
		current.effective_confidence = 0;
		strcpy(current.effective_word, " ");
		return current;
	}
}


//获取离线命令词识别结果
bool Get_Offline_Recognise_Result(const std::shared_ptr<wheeltec_mic_msg::srv::GetOfflineResultsrv::Request> req,
								  std::shared_ptr<wheeltec_mic_msg::srv::GetOfflineResultsrv::Response> res)
{
	offline_recognise_switch = req->offline_recognise_start;
	if (offline_recognise_switch == 1) //如果是离线识别模式
	{
		// ROS_INFO("open the offline recognise mode ...\n");
		// const char *file = join(source_path, DENOISE_SOUND_PATH);
		// remove(file);
		// start_to_record_denoised_sound();
		// int time_per = time_per_order;
		// if (req->time_per_order > 0)
		// {
		// 	time_per = req->time_per_order;
		// }
		// while (time_per--)
		// {
		// 	sleep(1);
		// }
		// finish_to_record_denoised_sound();
		// char *pcm_path = join(source_path, DENOISE_SOUND_PATH);
		// std::string transfom_pcm = pcm_path;
		// unsigned char *unsignend_pcm_path = (unsigned char *)transfom_pcm.c_str();
		// std::string begin = "fo|";
		// char *jet_path = join((begin + source_path), ASR_RES_PATH);
		// char *grammer_build_path = join(source_path, GRM_BUILD_PATH);
		// char *bnf_path = join(source_path, GRM_FILE);
		
		// Recognise_Result result = deal_with(unsignend_pcm_path, jet_path, grammer_build_path, bnf_path, LEX_NAME);


		//start_to_record_denoised_sound();
		//[1-2].开始创建一次语音识别了,首先传递了一些参数,作为QISRbegin()的输入]
		whether_finised = 0;
		int ret = 0;
		ret = create_asr_engine(&asr_data);
		start_to_record_denoised_sound();
		set_target_led_on(set_led_id);
    
		if (MSP_SUCCESS != ret)
		{
#if whether_print_log
			printf("[01]创建语音识别引擎失败！\n");
#endif
		}

		printf(">>>>>开始一次语音识别！\n");


		//获取当前时间
		clock_t start, finish;
		double total_time;
		start = clock();
		while (whether_finised != 1)
		{
			finish = clock();
			total_time = (double)(finish - start) / CLOCKS_PER_SEC/2;
			if (total_time > req->time_per_order)
			{
				cout << "超出离线命令词最长识别时间\n"
					 << endl;
				break;
			}
		}
		finish_to_record_denoised_sound();
		set_target_led_on(99);
		usleep(300000);


		if (whole_result!="")
		{
			//printf(">>>>>全部返回结果:　[ %s ]\n", whole_result);
			Effective_Result effective_ans = show_result(whole_result);
			if (effective_ans.effective_confidence >= req->confidence_threshold) //如果大于置信度阈值则进行显示或者其他控制操作
			{
				printf(">>>>>是否识别成功: [ %s ]\n", "是");
				printf(">>>>>关键字的置信度: [ %d ]\n", effective_ans.effective_confidence);
				printf(">>>>>关键字识别结果: [ %s ]\n", effective_ans.effective_word);
				//发布结果
				//control_jetbot(effective_ans.effective_word);
				res->result = "ok";
				res->fail_reason = "";
				std::wstring wtxt = s2ws(effective_ans.effective_word);
				std::string txt_uft8 = ws2s(wtxt);
				res->text = txt_uft8;
				
				std_msgs::msg::String msg;
				msg.data = effective_ans.effective_word;
				voice_words_pub->publish(msg);
				
			}
			else
			{
				printf(">>>>>是否识别成功: [ %s ]\n", "否");
				printf(">>>>>关键字的置信度: [ %d ]\n", effective_ans.effective_confidence);
				printf(">>>>>关键字置信度较低，文本不予显示\n");
				res->result = "fail";
				res->fail_reason = "low_confidence error or 11212_license_expired_error";
				res->text = " ";
			}
		}
		else
		{
			res->result = "fail";
			res->fail_reason = "no_valid_sound error";
			res->text = " ";
			printf(">>>>>未能检测到有效声音,请重试\n");
		}
		whole_result = "";
		//[1-3]语音识别结束]
		delete_asr_engine();
		write_first_data = 0;
		//is_awake = 0;
		
	}
	printf(" \n");
	printf(" \n");
	//ROS_INFO("close the offline recognise mode ...\n");
	return true;
}


/*
content:获取麦克风音频,if msg==1,开启录音并实时发布，若msg==0,关闭录音
data :20200407 PM
*/
//void Record_Start(const wheeltec_mic_msg::srv::StartRecordsrv::Request req, wheeltec_mic_msg::srv::StartRecordsrv::Response res)
void Record_Start(const std::shared_ptr<wheeltec_mic_msg::srv::StartRecordsrv::Request> req, std::shared_ptr<wheeltec_mic_msg::srv::StartRecordsrv::Response> res)
{
	if (req->whether_start == 1)
	{
		//ROS_INFO("got topic request,start to record ...\n");
		int ret1 = start_to_record_denoised_sound();
		if (ret1 == 0)
		{
			res->result = "ok";
			res->fail_reason = "";
		}
		else
		{
			res->result = "fail";
			res->fail_reason = "mic_did_not_open_error";
		}
	}
	else if (req->whether_start == 0)
	{
		//ROS_INFO("got topic request,stop to record ...\n");
		int ret2 = finish_to_record_denoised_sound();
		if (ret2 == 0)
		{
			res->result = "ok";
			res->fail_reason = "";
		}
		else
		{
			res->result = "fail";
			res->fail_reason = "mic_did_not_open_error";
		}
	}
	//return true;
}


/*
content:设置麦克风唤醒词4-6汉字
data :20200407 PM
*/
bool Set_Awake_Word(const std::shared_ptr<wheeltec_mic_msg::srv::SetAwakeWordsrv::Request> req,
					std::shared_ptr<wheeltec_mic_msg::srv::SetAwakeWordsrv::Response> res)
{
	//ROS_INFO("got request,start to correct awake word ...\n");
	if (strlen(req->awake_word.c_str()) >= 12 && strlen(req->awake_word.c_str()) <= 18) //4-6个汉字
	{
		Set_request_awake_word = false;
		int ret = set_awake_word(const_cast<char *>(req->awake_word.c_str()));
		if (ret == -3)
		{
			res->result = "fail";
			res->fail_reason = "mic_did_not_open_error";
			return true;
		}
		clock_t startTime, endTime;
		startTime = clock(); //计时开始
		while (!Set_request_awake_word)
		{
			endTime = clock();											  //计时开始
			if ((double)(endTime - startTime) / CLOCKS_PER_SEC > TIMEOUT) //等待时间大于5秒
			{
				res->result = "fail";
				res->fail_reason = "timeout_error";
				Set_request_awake_word = false;
				return true;
			}
		}
		Set_request_awake_word = false;
		res->result = "ok";
		res->fail_reason = "";
	}
	else
	{
		//ROS_INFO("got request,stop to correct awake word...\n");
		res->result = "fail";
		res->fail_reason = "invalid_awake word";
	}
	return true;
}

/*
content:设置灯亮,输入参数为0-11.99表示灯光关闭
data :20200407 PM
*/
bool Set_Led_On(const std::shared_ptr<wheeltec_mic_msg::srv::SetLedOnsrv::Request> req,
				std::shared_ptr<wheeltec_mic_msg::srv::SetLedOnsrv::Response> res)
{
	//ROS_INFO("got topic request,start to make the target led on ...\n");
	char str[256] = {0};
	sprintf(str, "%d", req->led_id);
	int ret1 = isnumber(str, 2);
	if (ret1 == 0)
	{
		if (req->led_id >= 0 && req->led_id <= 11 || req->led_id == 99)
		{
			int ret2 = set_target_led_on(req->led_id);
			if (ret2 == 0)
			{
				clock_t startTime, endTime;
				startTime = clock(); //计时开始
				while (!Set_request_led_id)
				{
					endTime = clock();											  //计时开始
					if ((double)(endTime - startTime) / CLOCKS_PER_SEC > TIMEOUT) //等待时间大于5秒
					{
						res->result = "fail";
						res->fail_reason = "timeout_error";
						Set_request_led_id = false;
						return true;
					}
				}
				Set_request_led_id = false;
				res->result = "ok";
				res->fail_reason = "";
			}
			else if (ret1 == -3)
			{
				res->result = "fail";
				res->fail_reason = "mic_did_not_open_error";
			}
		}
		else
		{
			res->result = "fail";
			res->fail_reason = "incorrect_led_id_error";
		}
	}
	else
	{
		res->result = "fail";
		res->fail_reason = "incorrect_led_id_error";
	}
	return true;
}

/*
content:设置主麦克风,麦克风共6个,输入参数为0-5.
data :20200407 PM
*/
bool Set_Major_Mic(const std::shared_ptr<wheeltec_mic_msg::srv::SetMajorMicsrv::Request> req,
				   std::shared_ptr<wheeltec_mic_msg::srv::SetMajorMicsrv::Response> res)
{
	//ROS_INFO("got topic request,start to make the target led on ...\n");
	char str[256] = {0};
	sprintf(str, "%d", req->mic_id);
	int ret1 = isnumber(str, 1);
	if (ret1 == 0)
	{
		if (req->mic_id >= 0 && req->mic_id <= 5)
		{
			int led_id = get_led_based_mic_id(req->mic_id);
			if (led_id == -3)
			{
				res->result = "fail";
				res->fail_reason = "mic_did_not_open_error";
			}
			else if (led_id == -2)
			{
				res->result = "fail";
				res->fail_reason = "incorrect_mic_id_error";
			}
			else
			{
				int ret2 = set_major_mic_id(req->mic_id);
				//if (whether_finised == 0)
				//{
					int ret3 = set_target_led_on(led_id);
				//}
				
				if (ret2 != -3 && ret2 != -2 && ret3 != -3 && ret3 != -2)
				{
					clock_t startTime, endTime;
					startTime = clock(); //计时开始
					while (!Set_request_mic_id && !Set_request_led_id)
					{
						endTime = clock();											  //计时开始
						if ((double)(endTime - startTime) / CLOCKS_PER_SEC > TIMEOUT) //等待时间大于5秒
						{
							res->result = "fail";
							res->fail_reason = "timeout_error";
							Set_request_mic_id = false;
							return true;
						}
					}
					Set_request_mic_id = false;
					
					res->result = "ok";
					res->fail_reason = "";
					
					set_led_id = led_id;
					//printf("led_id= %d\n",led_id);
					//printf("mic_id= %d\n",major_mic_id);
					
				}
				else if(ret2 == -3 || ret3 == -3) 
				{
					res->result = "fail";
					res->fail_reason = "mic_did_not_open_error";
				}
			}
		}
		else
		{
			res->result = "fail";
			res->fail_reason = "incorrect_mic_id_error";
		}
	}
	else
	{
		res->result = "fail";
		res->fail_reason = "incorrect_mic_id_error";
	}
	return true;
}


/*
content:获取主麦克风编号,当请求1时,调用该接口.
*/
bool Get_Major_Mic(const std::shared_ptr<wheeltec_mic_msg::srv::GetMajorMicsrv::Request> req,
				   std::shared_ptr<wheeltec_mic_msg::srv::GetMajorMicsrv::Response> res)
{
	if (req->get_major_id == 1)
	{
		//ROS_INFO("got request,start to get the major mic id ...\n");
		Get_request_mic_id = false;
		get_major_mic_id();
		clock_t startTime, endTime;
		startTime = clock(); //计时开始
		while (!Get_request_mic_id)
		{
			endTime = clock();											  //计时开始
			if ((double)(endTime - startTime) / CLOCKS_PER_SEC > TIMEOUT) //等待时间大于5秒
			{
				res->result = "fail";
				res->fail_reason = "timeout_error";
				Get_request_mic_id = false;
				return true;
			}
		}
		res->result = "ok";
		res->mic_id = major_mic_id;
		Get_request_mic_id = false;
	}
	return true;
}


/*
content:获取主麦克风编号,当请求1时,调用该接口.
*/
bool Get_Awake_Angle(const std::shared_ptr<wheeltec_mic_msg::srv::GetAwakeAnglesrv::Request> req,
					 std::shared_ptr<wheeltec_mic_msg::srv::GetAwakeAnglesrv::Response> res)
{
	if (req->get_awake_angle == 1)
	{
		//ROS_INFO("got request,start to get the major awake angle ...\n");
		clock_t startTime, endTime;
		startTime = clock(); //计时开始
		while (!Get_request_awake_angle)
		{
			endTime = clock();											  //计时开始
			if ((double)(endTime - startTime) / CLOCKS_PER_SEC > TIMEOUT) //等待时间大于5秒
			{
				res->result = "fail";
				res->fail_reason = "timeout_error";
				Get_request_awake_angle = false;
				return true;
			}
		}
		res->result = "ok";
		res->awake_angle = mic_angle;
	}
	return true;
}

void Cmd_Callback(const geometry_msgs::msg::Twist &cc)
{
  
  cout<<">>>>>Cmd_Callback"<<endl;
}

void *ThreadFun(void *arg)
{
    if (major_mic_id>5 || major_mic_id<0)
	{
		cout<<">>>>>未设置主麦，请唤醒或设置主麦"<<endl;
	}
	while (major_mic_id>5 || major_mic_id<0)
	{
		sleep(1);
	}
	cout<<">>>>>设置主麦成功！"<<endl;
	return NULL;
}


int main(int argc, char **argv)
{
    /* 初始化rclcpp  */
    rclcpp::init(argc, argv);
    auto node = std::make_shared<rclcpp::Node>("wheeltec_mic_msg");
    
	node->declare_parameter<int>("confidence",0);
	node->get_parameter_or<int>("confidence",  confidence,  0);

	node->declare_parameter<int>("seconds_per_order",3);
	node->get_parameter_or<int>("seconds_per_order",  time_per_order,  3);

	node->declare_parameter<std::string>("source_path","home/ros");
	node->get_parameter_or<std::string>("source_path",  source_path,  "/home/wheeltec/wheeltec_robot/src/xf_mic_asr__offline");

	node->declare_parameter<std::string>("appid","73bd9bcb");
	node->get_parameter_or<std::string>("appid",  appid,  "73bd9bcb");

	printf("-----confidence = %d\n",confidence);
	printf("-----time_per_order = %d\n",time_per_order);

	cout<<"source_path = "<<source_path<<endl;
	cout<<"appid = "<<appid<<endl;

	APPID = &appid[0];

	pub_pcm = node->create_publisher<wheeltec_mic_msg::msg::PcmMsg>("pcm_topic", 1);
	pub_awake_angle = node->create_publisher<std_msgs::msg::Int32>("awake_angle_topic", 1);
	major_mic_pub = node->create_publisher<std_msgs::msg::Int8>("major_mic_topic", 1);
	voice_words_pub = node->create_publisher<std_msgs::msg::String>("voice_words", 1);
	awake_flag_pub = node->create_publisher<std_msgs::msg::Int8>("awake_flag", 1);
	voice_flag_pub = node->create_publisher<std_msgs::msg::Int8>("voice_flag", 1);

	rclcpp::Service<wheeltec_mic_msg::srv::StartRecordsrv>::SharedPtr  service_record_start;
	//service_record_start = node->create_service<wheeltec_mic_msg::srv::StartRecordsrv>("start_record_srv",std::bind(&Record_Start, std::placeholders::_1, std::placeholders::_2));
	service_record_start = node->create_service<wheeltec_mic_msg::srv::StartRecordsrv>("start_record_srv",&Record_Start);

	rclcpp::Service<wheeltec_mic_msg::srv::GetOfflineResultsrv>::SharedPtr  service_get_wav_list;
	service_get_wav_list = node->create_service<wheeltec_mic_msg::srv::GetOfflineResultsrv>("get_offline_recognise_result_srv",&Get_Offline_Recognise_Result);

	rclcpp::Service<wheeltec_mic_msg::srv::SetMajorMicsrv>::SharedPtr  service_set_major_mic;
	service_set_major_mic = node->create_service<wheeltec_mic_msg::srv::SetMajorMicsrv>("set_major_mic_srv",&Set_Major_Mic);

	rclcpp::Service<wheeltec_mic_msg::srv::GetMajorMicsrv>::SharedPtr  service_get_major_mic;
	service_get_major_mic = node->create_service<wheeltec_mic_msg::srv::GetMajorMicsrv>("get_major_mic_srv",&Get_Major_Mic);

	rclcpp::Service<wheeltec_mic_msg::srv::SetLedOnsrv>::SharedPtr  service_set_led_on;
	service_set_led_on = node->create_service<wheeltec_mic_msg::srv::SetLedOnsrv>("set_target_led_on_srv",&Set_Led_On);

	rclcpp::Service<wheeltec_mic_msg::srv::SetAwakeWordsrv>::SharedPtr  service_set_awake_word;
	service_set_awake_word = node->create_service<wheeltec_mic_msg::srv::SetAwakeWordsrv>("set_awake_word_srv",&Set_Awake_Word);

	rclcpp::Service<wheeltec_mic_msg::srv::GetAwakeAnglesrv>::SharedPtr  service_get_awake_angle;
	service_get_awake_angle = node->create_service<wheeltec_mic_msg::srv::GetAwakeAnglesrv>("get_awake_angle_srv",&Get_Awake_Angle);


	sub_record_start = node->create_subscription<geometry_msgs::msg::Twist>("cmd_vel", 10, &Cmd_Callback);

	hid_device *handle = NULL;
	cout<<">>>>>打开麦克风设备，尝试连接"<<endl;

	handle = hid_open();//开启麦克风设备

	if (!handle)
	{
		printf(">>>>>无法打开麦克风设备，尝试重新连接进行测试\n");
		return -1;
	}
	cout<<">>>>>成功打开麦克风设备"<<endl;
	protocol_proc_init(send_to_usb_device, recv_from_usb_device, business_proc_callback, err_proc);
	get_system_status();//获取麦克风状态，是否正常工作

	std::string begin = "fo|";
	//std::string quit_begin = source_path;
	char *jet_path = join((begin + source_path), ASR_RES_PATH);
	char *grammer_path = join(source_path, GRM_BUILD_PATH);
	char *bnf_path = join(source_path, GRM_FILE);
	//IN_PCM = join(source_path, IN_PCM);
	//[1-1] 通用登录及语法构建
	
	Recognise_Result inital = initial_asr_paramers(jet_path, grammer_path, bnf_path, LEX_NAME);

	sleep(1);
	if (!is_boot)
	{
	
		cout<<">>>>>开机中，请稍等！"<<endl;
	}
	while (!is_boot)
	{
		if (is_reboot)
		{
			break;
		}
	}
	cout<<">>>>>开机成功！"<<endl;
	set_awake_word(awake_words);

	if(1)
	{
		std_msgs::msg::Int8 voice_flag_msg;
		voice_flag_msg.data = 1;
		voice_flag_pub->publish(voice_flag_msg);
	}

	pthread_t myThread1;
	int res = pthread_create(&myThread1, NULL, ThreadFun, NULL);
    if (res != 0) {
        printf("线程创建失败");
        //return 0;
    }

	RCLCPP_INFO(node->get_logger(), "wheeltec_mic_msg节点已经启动.");

	auto executor = std::make_shared<rclcpp::executors::MultiThreadedExecutor>();
  	// Add the node to the executor
  	executor->add_node(node);
	// Start spinning the executor asynchronously
  	executor->spin();
    
    /* 运行节点，并检测退出信号 Ctrl+C*/
    //rclcpp::spin(node);
	
    /* 停止运行 */
	hid_close();
    rclcpp::shutdown();
    return 0;
}

